<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 13.3.&nbsp; Coding Rules</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch13lev1sec2.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch13lev1sec4.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch13lev1sec3"></a>
<h3 class="docSection1Title">13.3. Coding Rules</h3>
<p class="docText">Some basic rules to coding a daemon prevent unwanted interactions from happening. We state these rules and then show a function, <tt>daemonize</tt>, that implements them.</P>
<div style="font-weight:bold"><ol class="docList" type="1"><LI><div style="font-weight:normal"><p class="docList">The first thing to do is call <tt>umask</tt> to set the file mode creation mask to 0. The file mode creation mask that's inherited could be set to deny certain permissions. If the daemon process is going to create files, it may want to set specific permissions. For example, if it specifically creates files with group-read and group-write enabled, a file mode creation mask that turns off either of these permissions would undo its efforts.</p></div></LI><LI><div style="font-weight:normal"><p class="docList">Call <tt>fork</tt> and have the parent <tt>exit</tt>. This does several things. First, if the daemon was started as a simple shell command, having the parent terminate makes the shell think that the command is done. Second, the child inherits the process group ID of the parent but gets a new process ID, so we're guaranteed that the child is not a process group leader. This is a prerequisite for the call to <tt>setsid</tt> that is done next.</P></div></li><LI><div style="font-weight:normal"><p class="docList">Call <tt>setsid</tt> to create a new session. The three steps listed in <a class="docLink" href="ch09lev1sec5.html#ch09lev1sec5">Section 9.5</a> occur. The process (a) becomes a session leader of a new session, (b) becomes the process group leader of a new process group, and (c) has no controlling terminal.</P><blockquote>
<p class="docText"><a name="idd1e95502"></a><a name="idd1e95509"></a><a name="idd1e95514"></a><a name="idd1e95519"></a><a name="idd1e95524"></a><a name="idd1e95529"></a><a name="idd1e95534"></a><a name="idd1e95539"></a>Under System Vbased systems, some people recommend calling <tt>fork</tt> again at this point and having the parent terminate. The second child continues as the daemon. This guarantees that the daemon is not a session leader, which prevents it from acquiring a controlling terminal under the System V rules (<a class="docLink" href="ch09lev1sec6.html#ch09lev1sec6">Section 9.6</a>). Alternatively, to avoid acquiring a controlling terminal, be sure to specify <tt>O_NOCTTY</tt> whenever opening a terminal device.</P>
</blockquote></div></li><LI><div style="font-weight:normal"><p class="docList">Change the current working directory to the root directory. The current working directory inherited from the parent could be on a mounted file system. Since daemons normally exist until the system is rebooted, if the daemon stays on a mounted file system, that file system cannot be unmounted.</p><p class="docList">Alternatively, some daemons might change the current working directory to some specific location, where they will do all their work. For example, line printer spooling daemons often change to their spool directory.</P></div></LI><LI><div style="font-weight:normal"><p class="docList">Unneeded file descriptors should be closed. This prevents the daemon from holding open any descriptors that it may have inherited from its parent (which could be a shell or some other process). We can use our <tt>open_max</tt> function (<a class="docLink" href="ch02lev1sec5.html#ch02fig16">Figure 2.16</a>) or the <tt>getrlimit</tt> function (<a class="docLink" href="ch07lev1sec11.html#ch07lev1sec11">Section 7.11</a>) to determine the highest descriptor and close all descriptors up to that value.</P></div></LI><li><div style="font-weight:normal"><p class="docList">Some daemons open file descriptors 0, 1, and 2 to <tt>/dev/null</tt> so that any library routines that try to read from standard input or write to standard output or standard error will have no effect. Since the daemon is not associated with a terminal device, there is nowhere for output to be displayed; nor is there anywhere to receive input from an interactive user. Even if the daemon was started from an interactive session, the daemon runs in the background, and the login session can terminate without affecting the daemon. If other users log in on the same terminal device, we wouldn't want output from the daemon showing up on the terminal, and the users wouldn't expect their input to be read by the daemon.</P></div></LI></ol></div>
<a name="ch13ex01"></a>
<h5 class="docExampleTitle">Example</h5>
<p class="docText"><a class="docLink" href="#ch13fig01">Figure 13.1</a> shows a function that can be called from a program that wants to initialize itself as a daemon.</p>
<p class="docText">If the <tt>daemonize</tt> function is called from a <tt>main</tt> program that then goes to sleep, we can check the status of the daemon with the <tt>ps</tt> command:</p>

<pre>
   $ <span class="docEmphStrong">./a.out</span>
   $ <span class="docEmphStrong">ps -axj</span>
    PPID   PID   PGID   SID TTY TPGID UID   COMMAND
       1  3346   3345  3345 ?      -1 501   ./a.out
   $ <span class="docEmphStrong">ps -axj |  grep 3345</span>
       1  3346   3345  3345 ?      -1 501   ./a.out
</pre><BR>

<p class="docText">We can also use <tt>ps</tt> to verify that no active process exists with ID 3345. This means that our daemon is in an orphaned process group (<a class="docLink" href="ch09lev1sec10.html#ch09lev1sec10">Section 9.10</a>) and is not a session leader and thus has no chance of allocating a controlling terminal. This is a result of performing the second <tt>fork</tt> in the <tt>daemonize</tt> function. We can see that our daemon has been initialized correctly.</p>

<a name="ch13fig01"></a>
<H5 class="docExampleTitle">Figure 13.1. Initialize a daemon process</h5>

<pre>
#include "apue.h"
#include &lt;syslog.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/resource.h&gt;

void
daemonize(const char *cmd)
{
    int                 i, fd0, fd1, fd2;
    pid_t               pid;
    struct rlimit       rl;
    struct sigaction    sa;
    /*
     * Clear file creation mask.
     */
    umask(0);

    /*
     * Get maximum number of file descriptors.
     */
    if (getrlimit(RLIMIT_NOFILE, &amp;rl) &lt; 0)
        err_quit("%s: can't get file limit", cmd);

    /*
     * Become a session leader to lose controlling TTY.
     */
    if ((pid = fork()) &lt; 0)
        err_quit("%s: can't fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);
    setsid();

    /*
     * Ensure future opens won't allocate controlling TTYs.
     */
    sa.sa_handler = SIG_IGN;
    sigemptyset(&amp;sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &amp;sa, NULL) &lt; 0)
        err_quit("%s: can't ignore SIGHUP");
    if ((pid = fork()) &lt; 0)
        err_quit("%s: can't fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);

    /*
     * Change the current working directory to the root so
     * we won't prevent file systems from being unmounted.
     */
    if (chdir("/") &lt; 0)
        err_quit("%s: can't change directory to /");

    /*
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i &lt; rl.rlim_max; i++)
        close(i);

    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.
     */
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    /*
     * Initialize the log file.
     */
    openlog(cmd, LOG_CONS, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d",
          fd0, fd1, fd2);
        exit(1);
    }
}
</pre><BR>



<ul></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch13lev1sec2.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch13lev1sec4.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--70-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--70-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
